package bomberman.swing;

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.ImageObserver;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.swing.JPanel;

import bomberman.model.Bom;
import bomberman.model.Boom;
import bomberman.model.Enemy;
import bomberman.model.Flame;
import bomberman.model.Man;
import bomberman.model.Property;
import bomberman.model.Stone;
import bomberman.model.Wall;
import bomberman.runable.MyRunableFresh;
import bomberman.runable.MyRunableMoveMan;
import bomberman.util.Constants;
import bomberman.util.GameMap;

public class BomJPanel extends JPanel implements ImageObserver, KeyListener {

	private static final long serialVersionUID = 1L;
	
	// 存放石头集合
	public static List<Stone> stones = new ArrayList<Stone>();
	
	// 存放砖头集合(在多线程中修改list用CopyOnWriteArrayList线程安全)
	public static List<Wall> walls = new CopyOnWriteArrayList<Wall>();
	
	// 存放炸弹集合 
	public static List<Bom> boms = new CopyOnWriteArrayList<Bom>();

	// 存放爆炸效果集合 
	public static List<Boom> booms = new CopyOnWriteArrayList<Boom>();
	
	// 存放道具集合
	public static List<Property> properties = new CopyOnWriteArrayList<Property>();
	
	// 存放火焰集合
	public static volatile List<Flame> flames = new CopyOnWriteArrayList<Flame>();
	
	// 存放炸弹坐标集合，人物放置炸弹并走出后添加，爆炸后移除
	public static Set<String> bom_bounds_sets = new CopyOnWriteArraySet<String>();
	
	// 全局临时变量，标记放置炸弹的坐标，当人物移出炸弹位置后重置为空
	public static String temp_bounds = "";
	
	// 全局随机数对象
	public static Random random = new Random();
	
	// 人
	public static Man man;

	// 存放敌人集合 
	public static List<Enemy> enemys = new CopyOnWriteArrayList<Enemy>();
	
	public BomJPanel(){
		init();
		
		// 开启 地图刷新线程 和 人物移动线程
//		MyRunableThreadPool.getExecutorService().execute(new MyRunableMoveMan());
//		MyRunableThreadPool.getExecutorService().execute(new MyRunableFresh(this));
		new Thread(new MyRunableMoveMan()).start();
		new Thread(new MyRunableFresh(this)).start();
		
		addKeyListener(this);
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		drawMap(g);
	}
	
	/**
	 * 初始化地图数据
	 */
	private void init() {
		for (int i = 0; i < GameMap.map.length; i++) {
			for (int j = 0; j < GameMap.map[i].length; j++) {
				switch (GameMap.map[i][j]) {
				case 1:
					man = new Man(j*30, i*30);
					break;
				case 2:
					walls.add(new Wall(j*30, i*30));
					new Property(j*30, i*30).randomProperty();
					break;
				case 3:
					stones.add(new Stone(j*30, i*30));
					break;
				case 4:
					enemys.add(new Enemy(j*30, i*30));
					break;
				case 6:
					properties.add(new Property(j*30, i*30));
					break;
				default:
					break;
				}
			}
		}
	}
	
	/**
	 * 画地图
	 * @param g
	 */
	public void drawMap(Graphics g){
		
		g.drawImage(GameMap.img_bg, 0, 0, this);
		
		// 画火焰
		for(Flame r : flames){
			r.draw(g);
		}
	
		// 画砖
		for(Wall r : walls){
			r.draw(g);
		}
		
		// 画爆炸效果
		for(Boom r : booms){
			r.draw(g);
		}

		// 画石头
		for(Stone r : stones){
			r.draw(g);
		}
		
		// 画炸弹
		for(Bom r : boms){
			r.draw(g);
		}
		
		// 画道具
		for(Property r : properties){
			r.draw(g);
		}

		// 画敌人
		for(Enemy r : enemys){
			r.draw(g);
		}
		
		// 画人
		man.draw(g);
	}

	@Override
	public void keyReleased(KeyEvent e) {
		switch (e.getKeyCode()) {
			case KeyEvent.VK_DOWN:
				Constants.DOWN = false;
				break;
			case KeyEvent.VK_UP:
				Constants.UP = false;
				break;
			case KeyEvent.VK_LEFT:
				Constants.LEFT = false;
				break;
			case KeyEvent.VK_RIGHT:
				Constants.RIGHT = false;
				break;
			default:
				break;
		}
	}

	@Override
	public void keyTyped(KeyEvent e) {
		
	}
	
	@Override
	public void keyPressed(KeyEvent e) {
		switch (e.getKeyCode()) {
			case KeyEvent.VK_DOWN:
				man.setDirection(Constants.MOVE_DOWN);
				Constants.DOWN = true;
				break;
			case KeyEvent.VK_UP:
				man.setDirection(Constants.MOVE_UP);
				Constants.UP = true;
				break;
			case KeyEvent.VK_LEFT:
				man.setDirection(Constants.MOVE_LEFT);
				Constants.LEFT = true;
				break;
			case KeyEvent.VK_RIGHT:
				man.setDirection(Constants.MOVE_RIGHT);
				Constants.RIGHT = true;
				break;
			case KeyEvent.VK_SPACE:	// 放置炸弹
				Bom bom = new Bom(man.getX(), man.getY());
				bom.addBom();
				break;
			default:
				break;
		}
	}
	
	
	
}
